<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Title</title>
  </head>
  <body>
  
  </body>
  <script>
    /* Array构造函数 */
    {
      const array1 = Array(3); // [空属性 × 3]
      console.log(array1)
      
      const array2 = Array(1, 2, 3);
      console.log(array2) // [1, 2, 3]
    }
    
    /* Array.from方法用于将类似数组的对象和可遍历对象(Set/Map)转为数组，Array.of方法用于将一组值转为数组 */
    {
      const arrLike = {
        '0': 'a',
        '1': 'b',
        '2': 'c',
        length: 3
      }
      const from1 = Array.from(arrLike);
      console.log(from1) // ['a', 'b', 'c']
      
      const from2 = Array.from([1, 2, 3], (x) => x ** 2);
      console.log(from2) // [1, 4, 9]
      
      const of = Array(1, 2, 3);
      console.log(of) // [1, 2, 3]
    }
    
    /* push方法用于在数组尾部添加元素并返回新数组长度，pop方法用于在数组尾部删除元素并返回被删除元素，二者都会影响原数组 */
    {
      let arrPush = ['11', '22', '33'];
      let push = arrPush.push('44');
      console.log(push);//4
      console.log(arrPush);//['11', '22', '33', '44']
      
      let arrPop = ['11', '22', '33'];
      let pop = arrPop.pop();
      console.log(pop);//33
      console.log(arrPop);//['11', '22']
    }
    
    /* shift方法用于在数组首部删除元素并返回被删除元素，unshift方法用于在数组首部添加元素并返回新数组长度，二者都会影响原数组 */
    {
      let arrShift = ['11', '22', '33'];
      let shift = arrShift.shift();
      console.log(shift);//11
      console.log(arrShift);//['22', '33']
      
      let arrUnshift = ['11', '22', '33'];
      let unshift = arrUnshift.unshift('00');
      console.log(unshift);//4
      console.log(arrUnshift);//['00', '11', '22', '33']
    }
    
    /* indexOf方法用于从前往后寻找指定元素，lastIndexOf方法用于从后往前寻找指定元素，二者都返回指定元素的索引 */
    {
      let arr = ['11', '22', '33'];
      
      let indexOf = arr.indexOf('11');
      console.log(indexOf);//0
      
      let lastIndexOf = arr.lastIndexOf('11');
      console.log(lastIndexOf);//0
    }
    
    /* includes方法用于判断数组是否包含给定的值，参数为`(给定值[, 开始索引])` */
    {
      const arr = [1, 2, 3, 4, 5]
      
      const includes1 = arr.includes(1);
      console.log(includes1) // true
      
      const includes2 = arr.includes(-1);
      console.log(includes2) // false
      
      const includes3 = arr.includes(1, 1);
      console.log(includes3) // false
      
      const includes4 = arr.includes(1, 0);
      console.log(includes4) // true
    }
    
    /* splice方法用于删除元素并返回被删除元素数组，参数为`(开始索引, [元素个数, 插入开始索引前的元素...])`，该方法会影响原数组 */
    {
      let arrSplice1 = ['11', '22', '33'];
      let splice1 = arrSplice1.splice(1);
      console.log(splice1);//['22', '33']
      console.log(arrSplice1);//['11']
      
      let arrSplice2 = ['11', '22', '33'];
      let splice2 = arrSplice2.splice(1, 1);
      console.log(splice2);//['22']
      console.log(arrSplice2);//['11', '33']
      
      let arrSplice3 = ['11', '22', '33'];
      let splice3 = arrSplice3.splice(1, 1, 'aa', 'bb', ['xx', 'yy']);
      console.log(splice3);//['22']
      console.log(arrSplice3);//['11', 'aa', 'bb', Array(2), '33']
    }
    
    /* slice方法用于截取元素并返回被截取元素数组，参数为`(开始索引, [结束索引])`，其中索引为负数时表示倒数索引。截取元素范围包括开始索引位置元素，不包含结束索引位置元素，该方法不会影响原数组 */
    {
      let arr = ['11', '22', '33'];
      
      let slice1 = arr.slice(1);
      console.log(slice1);//['22', '33']
      console.log(arr);//['11', '22', '33']
      
      let slice2 = arr.slice(1, 2);
      console.log(slice2);//['22']
      console.log(arr);//['11', '22', '33']
      
      let slice3 = arr.slice(-1);
      console.log(slice3);//['33']
      console.log(arr);//['11', '22', '33']
      
      let slice4 = arr.slice(-3, -2);
      console.log(slice4);//['11']
      console.log(arr);//['11', '22', '33']
      
      let slice5 = arr.slice(-2, -3);
      console.log(slice5);//[]
      console.log(arr);//['11', '22', '33']
    }
    
    /* concat方法用于拼接原数组与所有参数并返回拼接后的新数组，该方法不会影响原数组 */
    {
      let arr = ['11', '22', '33'];
      
      let concat = arr.concat('aa', 'bb', ['xx', 'yy'], {name: 'cyx'});
      console.log(concat);//['11', '22', '33', 'aa', 'bb', 'xx', 'yy', {name: 'cyx'}]
      console.log(arr);//['11', '22', '33']
    }
    
    /* copyWithin方法用于将指定位置的成员复制到其他位置，该方法会影响原数组 */
    {
      let arr = [1, 2, 3, 4, 5]
      // 将从3号位开始到结束(4和5)的数据，复制到从0号位开始的位置，结果覆盖了1和2
      arr.copyWithin(0, 3);
      console.log(arr) // [4, 5, 3, 4, 5]
    }
    
    /* fill方法用于填充数组，参数为`(填充字符串[, 开始索引, 结束索引])`，该方法会影响原数组 */
    {
      const arr1 = [1, 2, 3, 4, 5]
      arr1.fill("a");
      console.log(arr1) // ['a', 'a', 'a', 'a', 'a']
      
      const arr2 = [1, 2, 3, 4, 5]
      arr2.fill("b", 2, 4)
      console.log(arr2) // [1, 2, 'b', 'b', 5]
    }
    
    /* join方法用于以指定元素连接符来连接数组元素并返回连接后的字符串，默认元素连接符为逗号，该方法不会影响原数组 */
    {
      let arr = ['11', '22', '33'];
      
      let join1 = arr.join();
      console.log(join1);//11,22,33
      
      let join2 = arr.join(' -- ');
      console.log(join2);//11 -- 22 -- 33
    }
    
    /* reverse方法用于反转元素并返回反转后的新数组，该方法会影响原数组 */
    {
      let arrReverse = ['11', '22', '33'];
      let reverse = arrReverse.reverse();
      console.log(reverse);//['33', '22', '11']
      console.log(arrReverse);//['33', '22', '11']
    }
    
    /* sort方法用于元素排序并返回排序后的新数组，参数为指定好排序规则的回调函数，默认按照Unicode编码进行排序，该方法会影响原数组 */
    {
      let arrSort1 = [4, 2, 5, 2, 6];
      let sort1 = arrSort1.sort();
      console.log(sort1);//[2, 2, 4, 5, 6]
      console.log(arrSort1);//[2, 2, 4, 5, 6]
      
      let arrSort2 = [4, 2, 5, 2, 6];
      let sort2 = arrSort2.sort((a, b) => {
        return b - a;
      });
      console.log(sort2);//[6, 5, 4, 2, 2]
      console.log(arrSort2);//[6, 5, 4, 2, 2]
    }
    
    /* forEach方法用于遍历元素，参数为每次遍历都会被执行的回调函数，回调函数参数为`(当前元素, 当前索引, 数组对象)`，该方法不会影响原数组 */
    {
      let arr = ['11', '22', '33'];
      
      arr.forEach((value, index, object) => {
        console.log(object[index] === value);//true*3
      });
    }
    
    /* map方法用于映射元素并返回映射后的新数组，参数为映射回调函数，该方法不会影响原数组 */
    {
      let arr = ['11', '22', '33'];
      
      let mapRes = arr.map((item, index) => {
        return {
          index: index,
          value: item
        };
      });
      console.log(mapRes);//[{index: 0, value: '11'}, {index: 1, value: '22'}, {index: 2, value: '33'}]
      console.log(arr);//['11', '22', '33']
    }
    
    /* filter方法用于过滤元素并返回过滤后的新数组，参数为决定该元素是否被过滤的返回值为Boolean类型的回调函数，回调函数返回true则当前元素被保留，该方法不会影响原数组 */
    {
      let arr = ['11', '22', '33'];
      let filter = arr.filter((item, index) => index > 1);
      console.log(filter);//['33']
      console.log(arr);//['11', '22', '33']
    }
    
    /* every和some方法的参数为返回类型为Boolean的回调函数，若回调函数都返回true则every返回true，若回调函数任意一个返回true则some返回true */
    {
      let arr = ['11', '22', '33'];
      
      let every = arr.every(item => item < '55');
      console.log(every);//true
      
      let some = arr.some(item => item < '22');
      console.log(some);//true
    }
    
    /* find和findIndex方法分别用于找出第一个符合条件的成员或成员索引，参数为`(回调函数[, this值])`。find未找到则返回null，find Index未找到则返回-1 */
    {
      const arr = [1, 2, 3, 4, 5]
      
      const find = arr.find((value, index, obj) => value > 3);
      console.log(find) // 4
      
      const findIndex = arr.findIndex((value, index, obj) => value > 3);
      console.log(findIndex) // 3
      
      const findThis = arr.find(
          function (value) {
            return value > this.age
          },
          {
            age: 1
          });
      console.log(findThis) // 2
    }
    
    /* flat和flatMap方法用于将数组扁平化，默认只扁平化一层，二者都不会影响原数组 */
    {
      const arr = [1, 2, 3, [4, 5, [6, 7, 8]]]
      
      const flat1 = arr.flat();
      console.log(flat1) // [1, 2, 3, 4, 5, [6, 7, 8]]
      
      const flat2 = arr.flat(2);
      console.log(flat2) // [1, 2, 3, 4, 5, 6, 7, 8]
      
      // 相当于[[1, 2], [2, 4], [3, 6]].flat()
      const flatMap = [1, 2, 3].flatMap((item) => [item, item * 2])
      console.log(flatMap) // [1, 2, 2, 4, 3, 6]
    }
    
    /* reduce和reduceRight方法称为规约函数或合并函数，参数为`(回调函数(旧值，新值), 初始值)`。reduce方法用于从前往后规约，reduceRight方法用于从后往前规约，二者都不会影响原数组 */
    {
      let arr = [1, 2, 3, 4];
      
      let reduce = arr.reduce((oldVal, newVal) => {
        console.log(oldVal);//10 11 13 16
        console.log(newVal);//1  2  3  4
        return oldVal + newVal;
      }, 10);
      console.log(reduce);//20
      console.log(arr);//[1, 2, 3, 4]
      
      let reduceRight = arr.reduceRight((oldVal, newVal) => {
        console.log(oldVal);//10 14 17 19
        console.log(newVal);//4  3  2  1
        return oldVal + newVal;
      }, 10);
      console.log(reduceRight);//20
      console.log(arr);//[1, 2, 3, 4]
    }
  </script>
</html>